//////////////////////////////////////////////////////////////////////////////////////////
//                                                                                      //
//  Square Assault X																	//
//  Adventure of a Green Square in Deadly Maze                                          //
//                                                                                      //
//  Author: Jordan Brown (AKA Dr.Melon, Robowurmz)                                      //
//  Created: Mar 28, 2009										                        //
//  Uses libtcod.                                                                       //
//////////////////////////////////////////////////////////////////////////////////////////


/*

TODO SECTION

1. Get the map to read from a file. [X]
2. Introduce more tile types. [ ]
    2.5 Code complex tile interactions. [ ]
3. Optimise tile type storage. [X]
4. Make it a little prettier graphically. [X]
5. Code in game events (like start areas, goals). [X]
    5.5 Handle Game States. [?]
6. Make multiple levels. [X]
7. Make a menu. [ ]
8. Polish. [ ]
    8.5 AI Coding. [ ]
9. More Polish. (Not the country.) [ ]
    9.5 Cheats, *Fancy Explosions*, Bathtubs, whatnot. [ ]
10. Release demos and so on. [ ]
11. Add scripting maybe? [ ]
12. Release! [ ]


*/
// System #includes //////////////////////////////////////////////////////////////////////
#include <fstream>						 // FILE I/O
#include <iostream>						 // General I/O.
#include <sstream>                       // Stringstream.
#include <string>                        // Strings.

// Local #includes ///////////////////////////////////////////////////////////////////////
#include "libtcod.hpp"                   // Doryen Library
#include "player.h"                      // Player Class Declaration
#include "tiles.hpp"                     // Tile Type Declaration



using namespace std;


// Map dimensions
#define MAP_WIDTH	80
#define MAP_HEIGHT	30



// Globals ///////////////////////////////////////////////////////////////////////////////

// The map
int nMapArray[ MAP_HEIGHT ][ MAP_WIDTH ];
int nMapNumber; //Which number of map we are on. First is 0.
//TCODMap for FOV calculation - Darkest Spot
TCODMap *TCMap = new TCODMap(MAP_WIDTH, MAP_HEIGHT);
//TCODMap for FOV calculation - Penumbra
TCODMap *TCPMap = new TCODMap(MAP_WIDTH, MAP_HEIGHT);

// The player's location on the current map is stored in the Player class.


//What is the overall status of the player?
char * sPlayerStatus = "Alive";
char * cMapName = "Boing";
string sMapName;
string sMapFileName = "map.txt"; //Default map to load
string* maplist; //List of maps to load
int nCurrentMapNumber = 0;


// Start position
int nPlayerStartX;
int nPlayerStartY;

//Delta Positions
int nDeltaX = 0;
int nDeltaY = 0;



// Declare Player's Color
TCODColor cPlayGreen(0,127,0);
TCODColor nPlayerColor(cPlayGreen); //This is a Doryen-Compatible Colour Code. It's a rich Green colour.


// Is our player Dead?
bool bIsPlayerDead = false;

//Is smoke enabled right now?
bool bSmokeOn = true;

//Initialize the player class:
Player Ply1(1);


// Declare the player's character ( a square )
int nPlayer = 219;

// Is this level a dark level?
bool bDarkLevel = false;


bool bFinished = false; //Has our player finished the game (or run out of maps?)

//The Mini Console, used for a menu or somesuch.
TCODConsole *MiniConsole = new TCODConsole(20, 20);
bool bShowingMini = false;
bool bExploded = false; //This is so we can check to see if the player has already gone boom.


// DEBUG LOG
ofstream fDebugLog;



// Function Prototypes ///////////////////////////////////////////////////////////////////
void HandleInput( TCOD_key_t key );


void DrawMap( void );
bool IsPassable( int x, int y );
bool IsDeadly( int x, int y );
void DrawTile( int x, int y );
void DrawSmoke( int x, int y);
bool CheckForExit( int x, int y);
void LoadMap(int map[MAP_HEIGHT][MAP_WIDTH]);
string LoadMapCredentials( void );
void FillTCODMap(int MapArray[30][80], TCODMap *TMap);
void SwitchWalls( void );
void SwitchLava( void );
void ActivateSwitch( Player Ply);
void PlacePlayerStart( void );
void Scrambler( void ); //Cool scramble/matrix effect.
void ShowExplosion(int x, int y); //Show an "explosion" effect at co-ordinates X and Y.


void GoToNextLevel( void );
string* LoadMapList( void );//Load the list of maps.
char *append_char ( const char *s, const char c );


// For our Menu
void ShowMiniConsole ( void );


// IsPassable Function ///////////////////////////////////////////////////////////////////
//
//	This function analyzes the coordinates of the map array specified and returns
//	true if the coordinate is passable (able for the player to occupy), false if not.
//
bool IsPassable( int x, int y )
{
	// Before we do anything, make darn sure that the coordinates are valid
	if( x < 0 || x >= MAP_WIDTH || y < 0 || y >= MAP_HEIGHT )
		return false;

	// Store the value of the tile specified
	int nTileValue = nMapArray[y][x];

	fDebugLog << "Ran Passibility Check for Player Movement: Returned " << sTileIndex[nTileValue].bPassable << ".\n";

	// Return true if it's passable after consulting the tile index.
	return sTileIndex[nTileValue].bPassable;
}

// IsDeadly Function ///////////////////////////////////////////////////////////////////
//
//	This function analyzes the coordinates of the map array specified and returns
//	true if the coordinate is dangerous (kills the player), false if not.
//

bool IsDeadly( int x, int y)
{
	// Before we do anything, make darn sure that the coordinates are valid
	if( x < 0 || x >= MAP_WIDTH || y < 0 || y >= MAP_HEIGHT )
		return false;

	// Store the value of the tile specified
	int nTileValue = nMapArray[y][x];
	fDebugLog << "Ran Death Check. Returned: " << sTileIndex[nTileValue].bDangerous << ".\n";
	// Return true if it's deadly after consulting the tile index.
	return sTileIndex[nTileValue].bDangerous;

}

//CheckForExit Function /////////////////////////////////////////////////
//
//  This function checks to see if we are at the exit of a level.
//
//
bool CheckForExit( int x, int y)
{
	// Before we do anything, make darn sure that the coordinates are valid
	if( x < 0 || x >= MAP_WIDTH || y < 0 || y >= MAP_HEIGHT )
		return false;

	// Store the value of the tile specified
	int nTileValue = nMapArray[y][x];
	if (nTileValue == TILE_GOAL)
	{
        // Return true if it's a way out!
        return true;
	}

	return false; //Do nothing by default.

}


// DrawMap Function //////////////////////////////////////////////////////////////////////
//
//	This function draws the entire map to the screen.
//
void DrawMap( void )
{
	for( int y = 0; y < MAP_HEIGHT; y++ )
	{
		for( int x = 0; x < MAP_WIDTH; x++ )
		{
			DrawTile(x, y);
		}
	}
}

// DrawTile Function /////////////////////////////////////////////////////////////////////
//
//	Draws a map tile for the map coordinates specified.
//
void DrawTile( int x, int y ) // Make this Doryen-Compatible.
{


	// Record the tile type
	int nType = nMapArray[y][x];
	// Set up a color buffer for color mixing.
	TCODColor PenumbraMixed = TCODColor::lerp(sTileIndex[nType].nTileColor,TCODColor::black,0.35f);

    // Drawing the tiles normally.
    TCODConsole::root->setForegroundColor(sTileIndex[nType].nTileColor); //Doryen Tile Coloring
    TCODConsole::root->putChar(x, y, sTileIndex[nType].nCharacter, TCOD_BKGND_NONE) ; //Doryen Tile Printing, at X and Y.

    // Is this a "dark" level?
    if (bDarkLevel == true)
    {

        // Draw the penumbra shade, if it's in range.
        if (TCPMap->isInFov(x,y) == false)
        {
            TCODConsole::root->setForegroundColor(PenumbraMixed);
            TCODConsole::root->putChar(x,y, sTileIndex[nType].nCharacter, TCOD_BKGND_NONE);
        }

        // Draw the darkest shade, if it's in range.
        if (TCMap->isInFov(x,y) == false)
        {
            //Draw the darkest shade.
            TCODConsole::root->setForegroundColor(TCODColor::black);
            TCODConsole::root->putChar(x, y, 219, TCOD_BKGND_NONE) ;
        }

    }

}

// DrawSmoke Function /////////////////////////////////////////////////////////////////////
//
//	Draws a smoke tile for the map coordinates specified.
//
void DrawSmoke( int x, int y)
{

	//Change Map Array

	nMapArray[y][x] = TILE_SMOKE;

}





int main(int argc, char* argv[]) {
    // Open DebugLog. Write To Log.
    fDebugLog.open("DebugLog.txt");
	fDebugLog << "We are Opening the Window.\n";
    fDebugLog <<"Window Opened\n";
	//Open a TCOD Console Window.
    TCODConsole::initRoot(80,50,"Square Assault: Beta 0.10",false);
    TCODConsole::root->setForegroundColor(TCODColor::white);
    TCODSystem::setFps(30); //Switching to Realtime for rendering purposes.


    fDebugLog << "The Window has initialized successfully.\n";

    //Display Credits for Doryen
    TCODConsole::credits();


    //Load the Map by calling our LoadMap function.
    fDebugLog << "Loading Map Filenames...\n";

    //Can put this in initialization thing.
    maplist = LoadMapList();
    LoadMap(nMapArray);
    sMapName = LoadMapCredentials( );
    cMapName = (char * )sMapName.c_str();

    fDebugLog << "Initializing Player Start Positions, ASCII Characters, Colors and Any Other Specialties before Main Game Loop.\n";



	// Declare start position at first start tile encountered.
	PlacePlayerStart();
    Ply1.SetPos(nPlayerStartX, nPlayerStartY);


    // Doryen Keypress Thing
    TCOD_key_t key;



	fDebugLog << "Variables Initialized \n";



    fDebugLog << "Credits Displayed. Now beginning Main Loop!\n";


    //Main Game Loop.
    while (TCODConsole::isWindowClosed() != true)
    {
        //Refresh Console.
        TCODConsole::root->clear();

        // Turn Smoke Production off when we are not moving: otherwise, this makes smoke if we don't move!
		bSmokeOn = false;


        //Compute our field of view, once for the darkest, once for the penumbra - provided this is a dark level.
        if (bDarkLevel == true)
        {
            TCMap->computeFov(Ply1.GetPosX(),Ply1.GetPosY(),12,true,FOV_SHADOW);
            TCPMap->computeFov(Ply1.GetPosX(),Ply1.GetPosY(),10);
        }

        // Draw the map
		DrawMap();

        //Player Drawing

		TCODConsole::root->setForegroundColor(nPlayerColor); //This sets the colour to the Player's colour.
        TCODConsole::root->putChar(Ply1.GetPosX(), Ply1.GetPosY(), nPlayer, TCOD_BKGND_NONE) ; //This puts a square on the screen.

        //Draw a nice little window frame and a status window.
        TCODConsole::root->setForegroundColor(TCODColor::lightGrey);
        TCODConsole::root->printFrame(0,30,80,20,true,"Information");
        TCODConsole::root->printLeft(1,31,TCOD_BKGND_NONE, "Status: ");
        TCODConsole::root->printLeft(9,31,TCOD_BKGND_NONE, sPlayerStatus);
        TCODConsole::root->printLeft(1,32,TCOD_BKGND_NONE, "Level Name: ");
        TCODConsole::root->printLeft(13,32,TCOD_BKGND_NONE, cMapName);

        //If we are finished, draw some nice text.
        if (bFinished == true)
        {
            TCODConsole::root->setForegroundColor(TCODColor::yellow);
            TCODConsole::root->printCenter(39,14,TCOD_BKGND_NONE, "Wow! You either finished the game, or you've run out of maps!");

        }

		// Process the input - NOTE: SMOKE MUST BE TURNED ON BEFORE EVERY MOVE AND THEN TURNED OFF AGAIN.



        //See if we pressed a key.
        //Render To Console
        TCODConsole::flush();
        fDebugLog << "Checking for Keypresses.";
        key = TCODConsole::checkForKeypress();

		//This is the input function.
		HandleInput ( key );








        //This is the movement update code.
        // Check and see if we're allowed to move in the direction specified. Also, make sure we are not dead!
		if( IsPassable((Ply1.GetPosX()) + nDeltaX, (Ply1.GetPosY()) + nDeltaY) && (bIsPlayerDead == false) )
		{
		    fDebugLog << "Square is Passable.\n";
			// Produce smoke (WHEN SMOKE IS ENABLED AND ONLY ON VALID SQUARES).
			if (bSmokeOn == true)
			{


				int nTileValue = nMapArray[(Ply1.GetPosY())][(Ply1.GetPosX())];


				if (sTileIndex[nTileValue].bCanSmoke != false)
				{
				    fDebugLog << "Square can smoke.\n";
				DrawSmoke( (Ply1.GetPosX()), (Ply1.GetPosY()) );
				fDebugLog << "Square smoked.\n";
				}
			}
			// If allowed, move in the direction specified
			Ply1.SetPos(((Ply1.GetPosX()) + nDeltaX),((Ply1.GetPosY()) + nDeltaY));
            fDebugLog << "Player Moved, " << nDeltaX << " squares right, and " << nDeltaY << " squares down.\n";
            fDebugLog << "Player Position is:\n" << "X:\t" << Ply1.GetPosX() <<"\nY:\t" << Ply1.GetPosY() <<".\t";
		}

        if( IsDeadly((Ply1.GetPosX()), (Ply1.GetPosY())) )
		{
			// We should kill the player if the square is deadly.

			//Set the color to Red.
			TCODConsole::root->setForegroundColor(TCODColor::red);

			//Change the player into a little, sad hash symbol. :(
			nPlayer = 35;
			nPlayerColor = (TCODColor::red);
			bIsPlayerDead = true;
			if (bExploded == false)
			{
            ShowExplosion(Ply1.GetPosX(),Ply1.GetPosY()); //KABOOM!
            bExploded = true;
			}

			fDebugLog << "Player just died.\n";

			TCODConsole::flush();
			TCODConsole::root->checkForKeypress();
		}


        if( bIsPlayerDead == true)
        {
           //Tell them they are dead.
           sPlayerStatus = "Dead";
        }


        //Go to the next level if we are touching an exit tile.
       else if(CheckForExit((Ply1.GetPosX()),(Ply1.GetPosY())))
        {
            GoToNextLevel();
            Ply1.SetPos(nPlayerStartX, nPlayerStartY);
        }

        //Update the TCOD Map - if this is a dark level.
        if (bDarkLevel == true)
        {
            FillTCODMap(nMapArray,TCMap);
            FillTCODMap(nMapArray,TCPMap);
        }


    }
}




// Map Loading Algorithm

void LoadMap(int map[MAP_HEIGHT][MAP_WIDTH])
{

    int x;
    int y;
    ifstream sMapFile (maplist[nCurrentMapNumber].c_str()); //Load the map which is currently chosen from the list.
    if (sMapFile.is_open())
    {


        for (y=0; y<MAP_HEIGHT; y++)
        {

            for (x=0; x<MAP_WIDTH; x++)
            {
                sMapFile >> map[y][x];
            }

        }



    sMapFile.close();
    }
    else
    {
        sPlayerStatus = "Finished";
        bFinished = true;
    }


}

//This function allows us to load a name for the map from the line under the last line of the actual map data.

string LoadMapCredentials( void )
{
    //Load the name.

    ifstream nMapFile(maplist[nCurrentMapNumber].c_str());
    string s;
    string s2;


    nMapFile.seekg (0, ios::beg); // go to the first line

    for (int i=0; i<=(MAP_HEIGHT); i++) // loop 'till the desired line
        getline(nMapFile, s);
    fDebugLog << s;
    nMapFile.close();


        //Is this map dark?
    int isdark;


    nMapFile.open(maplist[nCurrentMapNumber].c_str());
    nMapFile.seekg (0, ios::beg); // Go to the first line

    for (int i=0; i<=(MAP_HEIGHT + 1); i++) // loop to desired line
        getline(nMapFile, s2);
    nMapFile.close();

    stringstream ss(s2);
    ss >> isdark;

    if (isdark == 1)
    {
        bDarkLevel = true;
    }
    else
    {
        bDarkLevel = false;
    }

        return s;
}
//This is the function that we will use to switch the walls from dark to light, and light to dark.


void SwitchWalls( void )
{

    for( int y = 0; y < MAP_HEIGHT; y++ )
    {
        for( int x = 0; x < MAP_WIDTH; x++ )
        {

           if (nMapArray[y][x] == TILE_WALL_DARK)
           {
               nMapArray[y][x] = TILE_WALL;
           }
           else if (nMapArray[y][x] == TILE_WALL)
           {
               nMapArray[y][x] = TILE_WALL_DARK;
           }

        }
    }

}

//This is the function that we will use to switch the lava from dark to light, and light to dark.


void SwitchLava( void )
{

    for( int y = 0; y < MAP_HEIGHT; y++ )
    {
        for( int x = 0; x < MAP_WIDTH; x++ )
        {

           if (nMapArray[y][x] == TILE_LAVA_DARK)
           {
               nMapArray[y][x] = TILE_LAVA_LIGHT;
           }
           else if (nMapArray[y][x] == TILE_LAVA_LIGHT)
           {
               nMapArray[y][x] = TILE_LAVA_DARK;
           }

        }
    }

}


// MAP FORMAT NOTES:
//// I have the grid, but I should also store things like the level's name and stuff at the bottom of the file. I should make the reader stop reading at the bottom of the map, and then read off additional data.


// MINI CONSOLE - THIS IS FOR A MENU OR SOMETHING
void ShowMiniConsole ( void )
{
        TCOD_key_t key;
        MiniConsole->setBackgroundColor(TCODColor::white);
        MiniConsole->setForegroundColor(TCODColor::red);
        MiniConsole->clear();
        MiniConsole->printFrame(0,0,20,20,false, NULL);
        MiniConsole->printCenter(10,0,TCOD_BKGND_NONE,"MENU PLACEHOLDER");
        MiniConsole->printCenter(10,3,TCOD_BKGND_NONE,"Quitting...");
        MiniConsole->printCenter(10,4,TCOD_BKGND_NONE,"Thanks for playing. :D");
        float angle;

        while (key.vk != TCODK_SPACE)
        {
        TCODConsole::blit(MiniConsole,0,0,20,20,TCODConsole::root,30,15,255);
        TCODConsole::flush();
        key = TCODConsole::checkForKeypress();
        }

}

void ShowExplosion ( int x, int y ) //Showing the explosion! :D
{
        float timer1 = 0;
        float angle;
        float scale = 0.30;
        TCODImage *explosionorange = new TCODImage("explosionorange.png");
        explosionorange->setKeyColor(TCODColor(255,0,255));
        TCODSystem::setFps(120);

        while (timer1 < 350)
        {
            timer1++;
            scale = scale + 0.05;
            angle = TCODSystem::getElapsedSeconds();
            TCODConsole::root->setBackgroundColor(TCODColor::black); //Refresh the screen on each update. Gets rid of that "trail". Also prevents things phasing around.
            TCODConsole::root->clear();
            explosionorange->blit(TCODConsole::root,(float)x,(float)y,TCOD_BKGND_SET,scale,scale,angle);
            TCODConsole::flush();
        }
        bExploded = true;
        TCODSystem::setFps(30);
}



void ActivateSwitch( Player Ply ) //Routine for flicking switches in the game.
{
                if (nMapArray[(Ply.GetPosY())][(Ply.GetPosX())] == TILE_SWITCH_WALLS)
                {
                SwitchWalls();

                }
                else if (nMapArray[(Ply.GetPosY())][(Ply.GetPosX())] == TILE_SWITCH_LAVA)
                {
                    SwitchLava();
                }
}

void PlacePlayerStart( void )
{
    //Cycle through all tiles looking for a start tile.
    for( int y = 0; y < MAP_HEIGHT; y++ )
    {
        for( int x = 0; x < MAP_WIDTH; x++ )
        {

           if (nMapArray[y][x] == TILE_START)
           {
               nPlayerStartX = x; //Change start position to the position of the start tile.
               nPlayerStartY = y;
           }



        }
    }

}

//This function makes a matrix-like scrambling effect.
void Scrambler( void )
{

    int pX; //X Position
    int pY; //Y position
    int timer = 0; //Timer
    TCOD_key_t key;
    TCODSystem::setFps(50); // increase framerate to 50 frames per second


    while ( timer < 1500 )
      { //Loop until key is pressed.

        TCODConsole::flush();
        // calculate a random position to draw our text.
        pX=(int)rand()%81; //0-80

        pY=(int)rand()%31; //0-30

        // %2 is a good test for even or odd.
        // So we do light green or dark green
        // depending if the random
        // number is even or odd [half the time]
        if (rand()%2==0)
        {
                    TCODConsole::root->setForegroundColor(TCODColor::darkGreen);// Dark Green
        }
        else
        {
                    TCODConsole::root->setForegroundColor(TCODColor::green); //Normal Green
        }

        // again - testing for even or odd.
        if (rand()%2==0)
        {
            TCODConsole::root->printLeft(pX,pY,TCOD_BKGND_NONE, "0");
        }
        else
        {
            TCODConsole::root->printLeft(pX,pY,TCOD_BKGND_NONE, "1"); // odd
        }
        timer++;
    }
    TCODSystem::setFps(30);


}




// FUNCTION FOR CONCATENATING CHAR*'s WITH CHARS.
char *append_char ( const char *s, const char c )
{
  std::size_t len = std::strlen ( s );
  char *ret = new char[len + 2];

  std::strcpy ( ret, s );
  ret[len] = c;
  ret[len + 1] = '\0';

  return ret;
}

string* LoadMapList( void )
{
    ifstream sListFile ("maplist.txt");
    ifstream FileToCount("maplist.txt");
    if (sListFile.is_open())
    {
        //Find the amount of lines in a file
        string t;
        string line;
        int lineCount=0;
        short lines=0;

        while(getline(FileToCount, t, '\n'))
        ++lineCount;
        printf("Line Count = ");
        cout << lineCount;
        printf("\n");


        string *MapsToLoad = new string[lineCount]; //Declare an array as big as the amount of maps loaded.

        while ( getline (sListFile, line ).good () ) //Read into file as long as we are not at the end.
        {

            MapsToLoad[lines] = line;
            cout << MapsToLoad[lines] << endl;
            lines++;

        }
        return MapsToLoad;
        sListFile.close();

    }
    else
    {
        sPlayerStatus = "Finished";
        bFinished = true;
    }
    return NULL; //By default, do nothing.
}

void GoToNextLevel( void )
{
    nCurrentMapNumber++;
    LoadMap(nMapArray);
    sMapName = LoadMapCredentials();
    cMapName = (char * )sMapName.c_str();
    //Put Positions Back to where they should be!
    PlacePlayerStart();

}
void HandleInput( TCOD_key_t key )
{
    //... Check to see which key has been pressed.
    		switch( key.vk )
		{
			// Move up
			case TCODK_UP:
				nDeltaX = 0;
				nDeltaY = -1;
				bSmokeOn = true;
				break;

			// Move left
			case TCODK_LEFT:
				nDeltaX = -1;
				nDeltaY = 0;
				bSmokeOn = true;
				break;

			// Move right
			case TCODK_RIGHT:
				nDeltaX = 1;
				nDeltaY = 0;
				bSmokeOn = true;
				break;

			// Move down
			case TCODK_DOWN:
				nDeltaX = 0;
				nDeltaY = 1;
				bSmokeOn = true;
				break;

            case TCODK_ENTER: //Switch tiles if on a switch.
                ActivateSwitch(Ply1);
                break;

            case TCODK_DELETE: //Scrambletest
                Scrambler();
                break;

            case TCODK_BACKSPACE: //RESET MAP
                //First, Clear off all the smoke by reloading the map file.
                LoadMap(nMapArray);
                //Reset the start position.
                Ply1.SetPos(nPlayerStartX,nPlayerStartY);
                bSmokeOn = false;
                bIsPlayerDead = false;
                sPlayerStatus = "Alive";
                nPlayer = 219;
                nPlayerColor = (cPlayGreen);
                bExploded = false;
                break;

            case TCODK_ESCAPE: //Exit (-TODO: Bring up Menu) when Escape is pressed.
                bShowingMini = true;
                ShowMiniConsole();
                TCODConsole::root->flush();
                fDebugLog << "User is Quitting... closing Square Assault.\n";
				fDebugLog.close();

            default: //Any other key does nothing here
                nDeltaX = 0;
                nDeltaY = 0;
                bSmokeOn = false;
                break;
        }

}

void FillTCODMap( int MapArray[30][80], TCODMap *TMap)
{
    int nTileValue;
    //First, we want to read the types from the map.
    	for( int y = 0; y < 30; y++ )
            {
                for( int x = 0; x < 80; x++ )
                    {
                        nTileValue = MapArray[y][x];
                        TMap->setProperties(x,y,(sTileIndex[nTileValue].bTransparent),(sTileIndex[nTileValue].bPassable));
                    }
            }


}
